/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2024-07-18 09:57:00
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2024-07-18 15:24:48
 * @FilePath: /hw/110/Sig/testsig.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include<iostream>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
#include<sys/types.h>


void CleanupChild(int signo)
{
//   // v1
//     if (signo == SIGCHLD)
//     {
//         pid_t rid = waitpid(-1, nullptr, 0);
//         if (rid > 0)
//         {
//             std::cout << "wait child success: " << rid << std::endl;
//         }
//     }
//     std::cout << "wait sub process done" << std::endl;
    //v2
    // if (signo == SIGCHLD)
    // {
    //     while (true)
    //     {
    //         pid_t rid = waitpid(-1, nullptr, 0); // -1 : 回收任意一个子进程
    //         if (rid > 0)
    //         {
    //             std::cout << "wait child success: " << rid << std::endl;
    //         }
    //         else if(rid <= 0) break;
    //     }
    // }
    //v3
    if (signo == SIGCHLD)
    {
        while (true)
        {
            pid_t rid = waitpid(-1, nullptr, WNOHANG); // -1 : 回收任意一个子进程(非阻塞等待)
            if (rid > 0)
            {
                std::cout << "wait child success: " << rid << std::endl;
            }
            else if(rid <= 0) break;
        }
    }

}
int main()
{
     signal(SIGCHLD, CleanupChild);
    //signal(SIGCHLD, SIG_IGN);

    // 50个退出，50个没有
    for (int i = 0; i < 100; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            // child
            int cnt = 5;
            while (cnt--)
            {
                std::cout << "I am child process: " << getpid() << std::endl;
                sleep(1);
            }
            std::cout << "child process died" << std::endl;
            exit(0);
        }
    }

    // father
    while (true)
        sleep(1);
}
